package utils

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"github.com/wcharczuk/go-chart/v2"
	"github.com/wcharczuk/go-chart/v2/drawing"
	"math/rand"
	"strconv"
	"time"
)

const (
	lineChartXAxisName = "Date"
	lineChartYAxisName = "Count"
	lineChartHeight    = 700
	lineChartWidth     = 1280
	colorMultiplier    = 256
	imgStrPrefix       = "data:image/png;base64,"
)

var (
	lineChartStyle = chart.Style{
		Padding: chart.Box{
			Top:  30,
			Left: 150,
		},
	}

	timeFormat = chart.TimeDateValueFormatter
)

type LineYValue struct {
	Name   string
	Values []float64
}

// createLineChart 创建线性图
func CreateGraph(title string, endTime time.Time, values []LineYValue) (img bytes.Buffer, err error) {
	if len(values) == 0 {
		return
	}
	// 1、计算X轴
	lenX := len(values[0].Values)
	// X轴内容xValues 及 X轴坐标ticks
	var xValues []time.Time
	var ticks []chart.Tick

	// 按天计算
	//for i := lenX - 1; i >= 0; i-- {
	//	curTime := endTime.AddDate(0, 0, -i)
	//	xValues = append(xValues, curTime)
	//	ticks = append(ticks, chart.Tick{Value: getNsec(curTime), Label: timeFormat(curTime)})
	//
	//}

	for i := lenX - 1; i >= 0; i-- {
		curTime := endTime.AddDate(0, 0, -i)
		xValues = append(xValues, curTime)
		ticks = append(ticks, chart.Tick{Value: getNsec(curTime), Label: timeFormat(curTime)})

	}

	// 2、生成Series
	var series []chart.Series
	for _, yValue := range values {

		series = append(series, chart.TimeSeries{
			Name: yValue.Name,
			Style: chart.Style{
				// 随机渲染线条颜色
				StrokeColor: drawing.Color{
					R: uint8(rand.Intn(colorMultiplier)),
					G: uint8(rand.Intn(colorMultiplier)),
					B: uint8(rand.Intn(colorMultiplier)),
					A: uint8(colorMultiplier - 1), // 透明度
				},
			},
			XValues: xValues,
			YValues: yValue.Values,
		})

		var annotations []chart.Value2
		//var annotations []chart.TimeSeries

		for index, y := range yValue.Values {
			annotations = append(annotations, chart.Value2{
				Label: strconv.FormatFloat(y, 'f', -1, 64),
				//XValue: xValues,
				XValue: chart.TimeToFloat64(xValues[index]),
				//XValue: getNsec(endTime.AddDate(0, 0, -index)),
				YValue: y,
			})

			//annotations =  append(annotations, chart.TimeSeries{
			//	Name: strconv.FormatFloat(y, 'f', -1, 64),
			//	XValues: xValues,
			//	YValues: yValue.Values,
			//})

			fmt.Println(chart.TimeToFloat64(xValues[index]), y)
		}

		series = append(series, chart.AnnotationSeries{
			Annotations: annotations,
		})

	}

	// 3、新建图形
	graph := chart.Chart{
		Title:      title,
		Background: lineChartStyle,
		Width:      lineChartWidth,
		Height:     lineChartHeight,
		XAxis: chart.XAxis{
			Name:           lineChartXAxisName,
			ValueFormatter: timeFormat,
			Ticks:          ticks,
			Style: chart.Style{
				TextRotationDegrees: 45.0,
			},
		},

		YAxis: chart.YAxis{
			Name: lineChartYAxisName,
		},
		Series: series,
	}

	graph.Elements = []chart.Renderable{
		chart.LegendLeft(&graph),
	}

	// 4、输出目标
	img, err = writeLineChart(&graph)

	//writeLineChartToPng(&graph)

	return
}

// getNsec 获取纳秒数
func getNsec(cur time.Time) float64 {
	return float64(cur.Unix() * int64(time.Second))
}

func writeLineChart(c *chart.Chart) (img bytes.Buffer, err error) {
	var imgContent bytes.Buffer
	err = c.Render(chart.PNG, &imgContent)
	if err != nil {
		fmt.Println(err)
		return
	}

	img = imgContent
	//img = imgToStr(imgContent)

	return
}

func imgToStr(imgContent bytes.Buffer) string {
	return imgStrPrefix + base64.StdEncoding.EncodeToString(imgContent.Bytes())
}

func writeLineChartToPng(c *chart.Chart) (img string, err error) {
	//f, _ := os.Create("graph.png")
	//defer f.Close()
	//err = c.Render(chart.PNG, f)
	return
}
